/* vim:set noet ts=4: */
/** 
 * scim-python
 * 
 * Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 * $Id: $
 */
#include <Python.h>
#include "structmember.h"
#include "scim-python-event.h"

struct PyKeyEvent{
	PyObject_HEAD
	/* Type-specific fields go here. */
	KeyEvent event;
};

static PyObject *
PyKeyEvent_str(const PyKeyEvent* self)
{
	char buf[128];
	sprintf (buf, "KeyEvent(code=0x%08x, mask=0x%04x, layout=%d)",
				self->event.code, 
				self->event.mask, 
				self->event.layout);

	return PyString_FromString (buf);
}
static PyObject *
PyKeyEvent_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyKeyEvent *self;

	self = (PyKeyEvent *)type->tp_alloc(type, 0);
	return (PyObject *)self;
}

static int
PyKeyEvent_init(PyKeyEvent *self, PyObject *args, PyObject *kwds)
{
	uint32 c = 0, m = 0, l = 0;

	if (!PyArg_ParseTuple(args, "|III:__init__", &c, &m, &l))
		return -1;

	new (&self->event)KeyEvent (c, m, l);
	return 0;
}



static PyMethodDef PyKeyEvent_methods[] = {
#if 0
	{ "show_preedit_string", (PyCFunction)PythonInstance::_show_preedit_string, METH_NOARGS,
	 "Return the name, combining the first and last name"
	},
#endif
	{NULL}  /* Sentinel */
};

static PyMemberDef PyKeyEvent_members[] = {
	{NULL}  /* Sentinel */
};

static PyObject *
PyKeyEvent_get_code(PyKeyEvent *self, void *closure)
{
	return PyInt_FromLong((long)self->event.code);
}

static int
PyKeyEvent_set_code(PyKeyEvent *self, PyObject *value, void *closure)
{
	if (value == NULL) {
		PyErr_SetString(PyExc_TypeError,
						"Cannot delete the code attribute");
		return -1;
	}

	if (! PyInt_Check(value)) {
		PyErr_SetString(PyExc_TypeError, 
						"The code attribute value must be a int");
		return -1;
	}

	self->event.code = (uint32)PyInt_AS_LONG (value);	

	return 0;
}

static PyObject *
PyKeyEvent_get_mask(PyKeyEvent *self, void *closure)
{
	
	return PyInt_FromLong((long)self->event.mask);
}

static int
PyKeyEvent_set_mask(PyKeyEvent *self, PyObject *value, void *closure)
{
	if (value == NULL) {
		PyErr_SetString(PyExc_TypeError,
						"Cannot delete the mask attribute");
		return -1;
	}

	if (! PyInt_Check(value)) {
		PyErr_SetString(PyExc_TypeError, 
						"The mask attribute value must be a int");
		return -1;
	}

	self->event.mask = (uint32)PyInt_AS_LONG (value);	

	return 0;
}

static PyObject *
PyKeyEvent_get_layout(PyKeyEvent *self, void *closure)
{
	
	return PyInt_FromLong((long)self->event.layout);
}

static int
PyKeyEvent_set_layout(PyKeyEvent *self, PyObject *value, void *closure)
{
	if (value == NULL) {
		PyErr_SetString(PyExc_TypeError, 
					"Cannot delete the layout attribute");
		return -1;
	}

	if (! PyInt_Check(value)) {
		PyErr_SetString(PyExc_TypeError, 
					"The layout attribute value must be a int");
		return -1;
	}
 
	self->event.layout = (uint32)PyInt_AS_LONG (value);	

	return 0;
}

static PyGetSetDef PyKeyEvent_getseters[] = {
	{"code", (getter)PyKeyEvent_get_code, (setter)PyKeyEvent_set_code,
		"Key code", NULL},
	{"mask", (getter)PyKeyEvent_get_mask, (setter)PyKeyEvent_set_mask,
		"Key's mask", NULL},
	{"layout", (getter)PyKeyEvent_get_layout, (setter)PyKeyEvent_set_layout,
		"keyboard layout", NULL},
	{NULL}  /* Sentinel */
};

static PyTypeObject PyKeyEventType = {
	PyObject_HEAD_INIT(NULL)
	0,						 				/*ob_size*/
	"scim.KeyEvent", 						/*tp_name*/
	sizeof(PyKeyEvent), 					/*tp_basicsize*/
	0,						 				/*tp_itemsize*/
	0,										/*tp_dealloc*/
	0,			  						/*tp_print*/
	0,						 				/*tp_getattr*/
	0,										/*tp_setattr*/
	0,										/*tp_compare*/
	0,			  						/*tp_repr*/
	0,										/*tp_as_number*/
	0,			  						/*tp_as_sequence*/
	0,										/*tp_as_mapping*/
	0,			  						/*tp_hash */
	0,										/*tp_call*/
	(reprfunc)PyKeyEvent_str,   							/*tp_str*/
	0,					   				/*tp_getattro*/
	0,										/*tp_setattro*/
	0,					 					/*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT,						/*tp_flags*/
	"KeyEvent objects",		 /* tp_doc */
	0,					   /* tp_traverse */
	0,					   /* tp_clear */
	0,					   /* tp_richcompare */
	0,					   /* tp_weaklistoffset */
	0,					   /* tp_iter */
	0,					   /* tp_iternext */
	PyKeyEvent_methods,			 /* tp_methods */
	PyKeyEvent_members,			 /* tp_members */
	PyKeyEvent_getseters,						 /* tp_getset */
	0,						 /* tp_base */
	0,						 /* tp_dict */
	0,						 /* tp_descr_get */
	0,						 /* tp_descr_set */
	0,						 /* tp_dictoffset */
	0,						   /* tp_init */
	0,						 /* tp_alloc */
	0,				/* tp_new */	
};

PyObject *PyKeyEvent_New (const KeyEvent &key)
{
	PyKeyEvent *obj = PyObject_New (PyKeyEvent, &PyKeyEventType);
	new (&obj->event) KeyEvent (key);
	
	return (PyObject *)obj;
}


void init_event (PyObject *module)
{
	PyObject *dict;

	if (PyType_Ready(&PyKeyEventType) < 0)
		return;
	Py_INCREF(&PyKeyEventType);
	PyModule_AddObject(module, "KeyEvent", (PyObject *)&PyKeyEventType);

}

